package com.gpframework.module.process.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import com.gpframework.common.exception.BaseException;
import com.gpframework.common.exception.CustomException;
import com.gpframework.module.process.domain.GpProcessOverflowRate;
import com.gpframework.module.process.domain.req.GpProcessCostingUpdate;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gpframework.module.process.mapper.GpProcessCostingMapper;
import com.gpframework.module.process.domain.GpProcessCosting;
import com.gpframework.module.process.domain.vo.GpProcessCostingVo;
import com.gpframework.module.process.service.IGpProcessCostingService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
/**
 * @ClassName GpProcessCosting
 * @Author gpframework
 * @Date 2023-12-20
 * @Version 1.0.0
 * @Description 成本核算Service业务层处理
 */
@Service
public class GpProcessCostingServiceImpl extends ServiceImpl<GpProcessCostingMapper, GpProcessCosting> implements IGpProcessCostingService {

    /**
     * @Description 查询列表返回VO 用于返回给前端的列表接口
     * @Author gpframework
     * @Date 2023-12-20
     * @Param [lqw]
     * @Return List<GpProcessCostingVo>
     */
    @Override
    public List<GpProcessCostingVo> listVo(QueryWrapper<GpProcessCosting> lqw) {
        return this.baseMapper.listVo(lqw);
    }

    /**
     * @Description 通过查询详情VO 用于返回给前端的列详情接口
     * @Author gpframework
     * @Date 2023-12-20
     * @Param [id]
     * @Return GpProcessCostingVo
     */
    @Override
    public GpProcessCostingVo getVoById(Long id) {
        return this.baseMapper.getVo(id);
    }

    @Override
    public boolean edit(List<GpProcessCostingUpdate> list) {
        ArrayList<GpProcessCosting> gpProcessCostings = new ArrayList<>();
        for (GpProcessCostingUpdate gpProcessCostingUpdate : list) {
            GpProcessCosting gpProcessCosting = Convert.convert(new TypeReference<GpProcessCosting>() {}, gpProcessCostingUpdate);
            if (gpProcessCosting.getBackerNum() != null && gpProcessCosting.getBackerNum().compareTo(BigDecimal.ZERO) <= 0 ){
               throw new BaseException("底布数量不能小于等于0");
            }
            Integer quantity = gpProcessCosting.getQuantity() == null ? 0 : gpProcessCosting.getQuantity();
            Integer sizeBar = gpProcessCosting.getSizeBar() == null ? 0 : gpProcessCosting.getSizeBar();
            BigDecimal codingSpecificationsEmpty = gpProcessCosting.getCodingSpecificationsEmpty() == null ? BigDecimal.ZERO : gpProcessCosting.getCodingSpecificationsEmpty();
            BigDecimal backerNum = gpProcessCosting.getBackerNum() == null ? BigDecimal.ONE : gpProcessCosting.getBackerNum();
            BigDecimal codingSpecificationsSufficient = gpProcessCosting.getCodingSpecificationsSufficient() == null ? BigDecimal.ZERO : gpProcessCosting.getCodingSpecificationsSufficient();
            Integer totalSizeSufficient = gpProcessCosting.getTotalSizeSufficient() == null ? 0 : gpProcessCosting.getTotalSizeSufficient();
            Integer lossQuantity = gpProcessCosting.getLossQuantity() == null ? 0 : gpProcessCosting.getLossQuantity();
            //成品入库总码数（空）=成品条数*打码规格/空码+大小条码数
            gpProcessCosting.setTotalSizeEmpty(quantity*codingSpecificationsEmpty.intValue()+sizeBar);
            //成品总码数（足）=成品条数*打码规格/足码+大小条码数
            gpProcessCosting.setTotalSizeSufficient(codingSpecificationsSufficient.intValue()+sizeBar);
            //损耗数量=底布数量足码-成品总码数（足)
            gpProcessCosting.setLossQuantity(backerNum.intValue()-totalSizeSufficient.intValue());
            // 损耗率=损耗数量/底布数量足码
            gpProcessCosting.setLossRate(new BigDecimal(lossQuantity).divide(backerNum, RoundingMode.HALF_UP));
            //成本=（底布数量*底布单价+成品数量*加工费）/成品数量
            gpProcessCosting.setCost(gpProcessCosting.getBackerNum().multiply(gpProcessCosting.getBackerPrice()).add(gpProcessCosting.getProcessFee().multiply(BigDecimal.valueOf(gpProcessCosting.getQuantity()))).divide(BigDecimal.valueOf(gpProcessCosting.getQuantity()),2, RoundingMode.HALF_UP));
            gpProcessCostings.add(gpProcessCosting);
            }
        return this.updateBatchById(gpProcessCostings);
    }

    @Override
    public boolean copy(Long id, Integer copyNum) {
        GpProcessCosting gpProcessCosting = this.getById(id);
        if (gpProcessCosting == null) {
            return false;
        }
        for (int i = 0; i < copyNum; i++) {
            gpProcessCosting.setId(null);
            this.save(gpProcessCosting);
        }
        return true;
    }
}
